using IQIGame.Onigao.Framework;
using System;
using System.Collections.Generic;
using UnityEngine;

namespace IQIGame.Onigao.Game
{
    public class TimelineGroup
    {
        private ObjectPoolBase _assetPool;

        private List<TimelineAssetInfo> _assets;
        private Dictionary<int, TimelineAssetInfo> _assetMap;

        public TimelineGroup(Type entityType, float instanceAutoReleaseInterval, float instanceExpireTime,
            int sameResCapacity, int totalCapacity)
        {
            this._assetPool = FrameworkEntry.ObjectPoolMgr.CreateObjectPool(entityType, 1000, instanceExpireTime);
            this._assetPool.AutoReleaseInterval = instanceAutoReleaseInterval;
            this._assetPool.SameResCapacity = sameResCapacity;
            this._assetPool.TotalCapacity = totalCapacity;
            this._assets = new List<TimelineAssetInfo>();
            this._assetMap = new Dictionary<int, TimelineAssetInfo>();
        }

        public void OnUpdate(float deltaTime, float unScaledDeltaTime)
        {
            for (int i = 0; i < this._assets.Count; i++)
            {
                this._assets[i].OnUpdate(deltaTime, unScaledDeltaTime);
            }
        }

        public TimelineAssetInfo Get(int id, string assetName)
        {
            TimelineAssetInfo entity = (TimelineAssetInfo)this._assetPool.GetObject(assetName);
            entity.SetId(id);
            this._assets.Add(entity);
            this._assetMap[id] = entity;
            return entity;
        }

        /// <summary>
        /// 从实体组中获取实体。
        /// </summary>
        /// <param name="assetId">实体序列编号。</param>
        /// <returns>要获取的实体。</returns>
        public TimelineAssetInfo FindAsset(int assetId)
        {
            if (this._assetMap.TryGetValue(assetId, out var rAsset))
            {
                return rAsset;
            }
            return null;
        }

        /// <summary>
        /// 从实体组中获取实体。
        /// </summary>
        /// <param name="assetName">实体资源名称。</param>
        /// <returns>要获取的实体。</returns>
        public TimelineAssetInfo FindAsset(string assetName)
        {
            if (string.IsNullOrEmpty(assetName))
            {
                throw new FrameworkException("Entity asset name is invalid.");
            }

            for (int i = 0; i < this._assets.Count; i++)
            {
                TimelineAssetInfo entity = this._assets[i];
                if (entity.AssetName == assetName)
                {
                    return entity;
                }
            }

            return null;
        }

        private void InnerHideAsset(TimelineAssetInfo asset)
        {
            int entityId = asset.Id;
            if (this._assetMap.Remove(entityId))
            {
                this._assets.Remove(asset);
                this._assetPool.PutBackObject(asset);
            }
            else
            {
                LogGame.LogError("隐藏实体失败，实体对象已不在实体组中，可能已经被隐藏。");
            }
        }

        public void HideAsset(int entityId)
        {
            this.HideAsset(this.FindAsset(entityId));
        }

        public void HideAsset(TimelineAssetInfo entity)
        {
            if (entity == null)
            {
                return;
            }
            entity.CancelLoading();
            this.InnerHideAsset(entity);
        }

        public void HideAll()
        {
            for (int i = this._assets.Count - 1; i >= 0; i--)
            {
                this.HideAsset(this._assets[i]);
            }
        }

        public void Dispose()
        {
            HideAll();
            FrameworkEntry.ObjectPoolMgr.DestroyObjectPool(this._assetPool);
        }
    }
}
